package com.vortex.cloud.sample.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.vortex.cloud.sample.domain.TaskUser;
import com.vortex.cloud.sample.dto.DictDataDTO;
import com.vortex.cloud.sample.dto.TaskUserDTO;
import com.vortex.cloud.sample.dto.TaskUserQueryDTO;
import com.vortex.cloud.sample.enums.Position;
import com.vortex.cloud.sample.enums.RoleType;
import com.vortex.cloud.sample.enums.Sex;
import com.vortex.cloud.sample.manager.UmsManagerService;
import com.vortex.cloud.sample.mapper.TaskUserMapper;
import com.vortex.cloud.sample.service.TaskUserService;
import com.vortex.cloud.sample.utils.MD5Utils;
import com.vortex.cloud.sample.vo.TaskUserVo;
import com.vortex.cloud.vfs.lite.base.dto.DataStoreDTO;
import com.vortex.cloud.vfs.lite.base.dto.RestResultDTO;
import com.vortex.cloud.vfs.lite.data.util.PageUtils;
import javafx.scene.transform.Rotate;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import javax.xml.crypto.Data;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 王林
 * @version 1.0
 * @date 2021-10-13 周三
 * @time 15:11
 * @description
 */
@Service
public class TaskUserServiceImpl extends ServiceImpl<TaskUserMapper, TaskUser> implements TaskUserService {

    @Resource
    private TaskUserMapper taskUserMapper;

    @Resource
    private UmsManagerService umsManagerService;

    @Transactional(rollbackFor = Exception.class)
    @Override

    public RestResultDTO<String> save(String tenantId, TaskUserDTO dto) {
        if (StringUtils.isBlank(tenantId)) {
            return RestResultDTO.newFail("租户Id不能为空");
        }

        if (Objects.isNull(dto.getRoleType())) {
            return RestResultDTO.newFail("角色不能为空");
        }

        RoleType roleType = RoleType.getByCode(dto.getRoleType());
        if ((roleType.equals(RoleType.ADMIN))) {
            return RestResultDTO.newFail("不能新增管理员");
        }

        if (StringUtils.isBlank(dto.getName())) {
            return RestResultDTO.newFail("姓名不能为空");
        }

        if (StringUtils.isBlank(dto.getSex())) {
            return RestResultDTO.newFail("性别不能为空");
        }

        if (StringUtils.isBlank(dto.getIdNo())) {
            return RestResultDTO.newFail("身份证号码不能为空");
        }
        if (!dto.getIdNo().matches("^\\d{15}|\\d{18}$")) {
            return RestResultDTO.newFail("身份证号码传入错误");
        }

        if (StringUtils.isBlank(dto.getMobileNo())) {
            return RestResultDTO.newFail("手机号码不能为空");
        }
        if (!dto.getMobileNo().matches("^1[0-9]{10}$")) {
            return RestResultDTO.newFail("手机号码传入错误");
        }

        if (StringUtils.isBlank(dto.getPosition())) {
            return RestResultDTO.newFail("职位不能为空");
        }
        Position position = Position.getByCode(dto.getPosition());
        if (Objects.isNull(position)) {
            return RestResultDTO.newFail("职位传入错误");
        }
        List<Position> roleTypeList = Position.getByRoleType(roleType);
        Optional<Position> positionRight = roleTypeList.stream().filter(it -> it == position).findAny();
        if (!positionRight.isPresent()) {
            return RestResultDTO.newFail("职位传入与角色不匹配错误");
        }

        if (StringUtils.isBlank(dto.getEmail())) {
            return RestResultDTO.newFail("邮箱不能为空");
        }
        if (roleType == RoleType.STUDENT) {
            if (!dto.getEmail().matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$")) {
                return RestResultDTO.newFail("邮箱传入错误");
            }
        }
        // 存在性检查
        LambdaQueryWrapper<TaskUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(TaskUser::getTenantId, tenantId);
        lqw.eq(TaskUser::getRoleType, roleType.getCode());
        TaskUser taskUser = taskUserMapper.selectOne(lqw);
        if (Objects.nonNull(taskUser)) {
            return RestResultDTO.newFail("账号对应角色已经存在");
        }
        lqw = Wrappers.lambdaQuery();
        lqw.eq(TaskUser::getIdNo, dto.getIdNo());
        taskUser = taskUserMapper.selectOne(lqw);
        if (Objects.nonNull(taskUser)) {
            return RestResultDTO.newFail("身份证号已经存在");
        }

        TaskUser insertTaskUser = new TaskUser();
        BeanUtils.copyProperties(dto, insertTaskUser);
        insertTaskUser.setTenantId(tenantId);

        // 新增用户标记为首次登录 需要修改密码
        insertTaskUser.setIsFirstLogin("1");

        // 密码默认为身份证后六位
        String password = dto.getIdNo().substring(dto.getIdNo().length() - 6);
        // 密码加密
        password = MD5Utils.EncodeMD5(password);
        insertTaskUser.setPassword(password);

        String currentUser = "王林";
        insertTaskUser.setCreateBy(currentUser);
        insertTaskUser.setUpdateBy(currentUser);
        // 初始化密码
        int insert = taskUserMapper.insert(insertTaskUser);
        return insert > 0 ? RestResultDTO.newSuccess("新增成功") : RestResultDTO.newFail("新增失败");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RestResultDTO<String> update(String id, TaskUserDTO dto) {
        if (StringUtils.isBlank(id)) {
            return RestResultDTO.newFail("用户ID不能为空");
        }

        TaskUserVo taskUser = getInfoById(id);
        if (Objects.isNull(taskUser)) {
            return RestResultDTO.newFail("用户不存在");
        }

        if (StringUtils.isNotBlank(dto.getPosition())) {
            List<Position> roleTypeList = Position.getByRoleType(taskUser.getRoleType());
            Position position = Position.getByCode(dto.getPosition());
            Optional<Position> positionRight = roleTypeList.stream().filter(it -> it == position).findAny();
            if (!positionRight.isPresent()) {
                return RestResultDTO.newFail("职位传入与角色不匹配错误");
            }
        }

        if (StringUtils.isNotBlank(dto.getIdNo())) {
            if (!dto.getIdNo().matches("^\\d{15}|\\d{18}$")) {
                return RestResultDTO.newFail("身份证号码传入错误");
            }
            LambdaQueryWrapper<TaskUser> lqw = Wrappers.lambdaQuery();
            lqw.eq(TaskUser::getIdNo, dto.getIdNo());
            List<TaskUser> originTaskUserList = taskUserMapper.selectList(lqw);
            if (CollectionUtils.isNotEmpty(originTaskUserList)) {
                if (originTaskUserList.size() > 1) {
                    return RestResultDTO.newFail("身份证号已经存在");
                }
            }
        }

        if (StringUtils.isNotBlank(dto.getSex())) {
            Sex sex = Sex.getByCode(dto.getSex());
            if (Objects.isNull(sex)) {
                return RestResultDTO.newFail("性别传入错误");
            }
        }
        if (StringUtils.isNotBlank(dto.getMobileNo())) {
            if (!dto.getMobileNo().matches("^1[0-9]{10}$")) {
                return RestResultDTO.newFail("手机号码传入错误");
            }
        }
        if (StringUtils.isNotBlank(dto.getEmail())) {
            if (!dto.getEmail().matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$")) {
                return RestResultDTO.newFail("邮箱传入错误");
            }
        }
        int update = taskUserMapper.update(null, new LambdaUpdateWrapper<TaskUser>()
                .set(StringUtils.isNotBlank(dto.getName()), TaskUser::getName, dto.getName())
//                .set(StringUtils.isNotBlank(tenantId), TaskUser::getTenantId, tenantId)
                .set(StringUtils.isNotBlank(dto.getIdNo()), TaskUser::getIdNo, dto.getIdNo())
                .set(StringUtils.isNotBlank(dto.getSex()), TaskUser::getSex, dto.getSex())
                .set(StringUtils.isNotBlank(dto.getMobileNo()), TaskUser::getMobileNo, dto.getMobileNo())
                .set(StringUtils.isNotBlank(dto.getPosition()), TaskUser::getPosition, dto.getPosition())
                .set(StringUtils.isNotBlank(dto.getEmail()), TaskUser::getEmail, dto.getEmail())
                .set(StringUtils.isNotBlank(dto.getMobileNo()), TaskUser::getMobileNo, dto.getMobileNo())
                .set(Objects.nonNull(dto.getTaskDate()), TaskUser::getTaskDate, dto.getTaskDate())
                .set(Objects.nonNull(dto.getTaskTime()), TaskUser::getTaskTime, dto.getTaskTime())
                .set(Objects.nonNull(dto.getTaskDateTime()), TaskUser::getTaskDateTime, dto.getTaskDateTime())
//                .set(TaskUser::getUpdateBy, UserContext.get().getName())
                .set(TaskUser::getUpdateBy, "王林")
//                .set(TaskUser::getUpdateTime, DateUtils.getLocalDateTime())
                .eq(TaskUser::getId, id));
        return update > 0 ? RestResultDTO.newSuccess("更新成功") : RestResultDTO.newFail("更新失败");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(Set<String> ids) {
        if (CollectionUtils.isNotEmpty(ids)) {
            taskUserMapper.deleteBatchIds(ids);
        }
    }

    @Override
    public DataStoreDTO<TaskUserVo> page(String tenantId, Pageable pageable, TaskUserQueryDTO params) {
        QueryWrapper<TaskUser> queryWrapper = this.buildQuery(tenantId, params);
        Page<TaskUser> page = PageUtils.transferPage(pageable);
        Page<TaskUser> result = taskUserMapper.selectPage(page, queryWrapper);
        return new DataStoreDTO(result.getTotal(), this.transferFromEntity(tenantId, result.getRecords()));
    }

    @Override
    public DataStoreDTO<TaskUserVo> listPage(Pageable pageable, TaskUserQueryDTO params) {

        LambdaQueryWrapper<TaskUser> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(params.getName()), TaskUser::getName, params.getName());
        Page<TaskUser> page = PageUtils.transferPage(pageable);
        Page<TaskUser> result = taskUserMapper.selectPage(page, lqw);

        List<TaskUserVo> taskVOList = result.getRecords().stream().map(entity -> {
            TaskUserVo vo = new TaskUserVo();
            BeanUtils.copyProperties(entity, vo);
            return vo;
        }).collect(Collectors.toList());

        return new DataStoreDTO(result.getTotal(), taskVOList);
    }

    private QueryWrapper<TaskUser> buildQuery(String tenantId, TaskUserQueryDTO params) {
        QueryWrapper<TaskUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TaskUser::getTenantId, tenantId);
        queryWrapper.lambda().like(StringUtils.isNotBlank(params.getName()), TaskUser::getName, params.getName());
//                .eq(Objects.nonNull(params.getTaskDate()), TaskUser::getTaskDate, params.getTaskDate())
//                .eq(Objects.nonNull(params.getTaskTime()), TaskUser::getTaskTime, params.getTaskTime())
//                .eq(Objects.nonNull(params.getTaskDateTime()), TaskUser::getTaskDateTime, params.getTaskDateTime())
//                .eq(StringUtils.isNotBlank(params.getRoleType()), TaskUser::getRoleType, params.getRoleType())
//                .eq(StringUtils.isNotBlank(params.getIdNo()), TaskUser::getIdNo, params.getIdNo())
//                .eq(StringUtils.isNotBlank(params.getSex()), TaskUser::getSex, params.getSex())
//                .eq(StringUtils.isNotBlank(params.getMobileNo()), TaskUser::getMobileNo, params.getMobileNo())
//                .eq(StringUtils.isNotBlank(params.getPosition()), TaskUser::getPosition, params.getPosition())
//                .eq(StringUtils.isNotBlank(params.getEmail()), TaskUser::getEmail, params.getEmail());

        return queryWrapper;
    }

    private List<TaskUserVo> transferFromEntity(String tenantId, List<TaskUser> entities) {
        if (CollectionUtils.isEmpty(entities)) {
            return Lists.newArrayList();
        }
        Map<String, DictDataDTO> UMS_DIVISION_SDK_MAP = umsManagerService.mapDictData(UmsManagerService.SDK_OBJECT_CODE_DIVISION, tenantId, null);
        Map<String, DictDataDTO> UMS_DEPT_ORG_SDK_MAP = umsManagerService.mapDictData(UmsManagerService.SDK_OBJECT_CODE_DEPT_ORG, tenantId, null);
        Map<String, DictDataDTO> UMS_STAFF_SDK_MAP = umsManagerService.mapDictData(UmsManagerService.SDK_OBJECT_CODE_STAFF, tenantId, null);
        Map<String, DictDataDTO> UMS_USER_SDK_MAP = umsManagerService.mapDictData(UmsManagerService.SDK_OBJECT_CODE_USER, tenantId, null);
        Map<String, DictDataDTO> UMS_PARAM_SETTING_SDK_MAP = umsManagerService.mapDictData(UmsManagerService.SDK_OBJECT_CODE_PARAM_SETTING, tenantId, null);

        List<TaskUserVo> taskVOList = entities.stream().map(entity -> {
            TaskUserVo vo = new TaskUserVo();
            BeanUtils.copyProperties(entity, vo);
            // 填充数据字典
//            vo.setDivisionId(UMS_DIVISION_SDK_MAP.get(entity.getDivisionId()));
//            vo.setStaffId(UMS_STAFF_SDK_MAP.get(entity.getStaffId()));
            return vo;
        }).collect(Collectors.toList());

//        // 偏转经纬度
//        lbsManagerService.transferFromEntityList(entities, taskVOList, coordinateType);

        return taskVOList;
    }


    @Override
    public TaskUserVo getInfoById(String id) {
        LambdaQueryWrapper<TaskUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(TaskUser::getId, id);
        lqw.eq(TaskUser::getDeleted, "0");
        TaskUser taskUser = taskUserMapper.selectById(id);
        if (Objects.isNull(taskUser)) {
            throw new RuntimeException("用户不存在");
        }
        TaskUserVo user = new TaskUserVo();
        BeanUtils.copyProperties(taskUser, user);
        return user;
    }


}
